package it.unica.informatica.enotes.manager;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Base64;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;

import it.unica.informatica.enotes.notes.Note;
import it.unica.informatica.enotes.notes.AttachmentItem;

/**
 * This class perform all the translations between a note object and its json decode
 *
 * @author Mirko Marras
 * @version 1.0
 */
public class JsonManager {

   private static final String KEY_TEXT_CONTENT = "text_content";
   private static final String KEY_ATTACH_ITEMS = "attach_item";
   private static final String KEY_ATTACH_NAME = "attach_name";
   private static final String KEY_ATTACH_TYPE = "attach_type";
   private static final String KEY_ATTACH_THUMBNAILS = "attach_thumbnails";

   /**
    * Get the ASCII string that contains the text content of the note based on the JSON string
    *
    * @param extraData The JSON string that encapsulates the content of a note
    * @return The ASCII string that contains the text content of the note based on the JSON string
    */
   public static String getNoteContent(String extraData) {
      try {
         /* Create a JSONObject from the string parameter */
         JSONObject jsonNoteContent = (JSONObject) new JSONParser().parse(extraData);

         /* If the JSONObject is correctly created, return the note text content contained in the JSON */
         if (jsonNoteContent != null) {
            return (String) jsonNoteContent.get(KEY_TEXT_CONTENT);
         }
      } catch (ParseException e) {
         e.printStackTrace();
      }

      return "";
   }

   /**
    * Get the list of all the attachments of the note based on the JSON string
    *
    * @param extraData The JSON string that encapsulates the content of a note
    * @return The list of all the attachments of the note based on the JSON string
    */
   public static ArrayList<AttachmentItem> getNoteAttachments(String extraData) {
      /* This ArrayList will store all the retrieved note attachments */
      ArrayList<AttachmentItem> attachments = new ArrayList<AttachmentItem>();

      JSONObject jsonNoteContent = null;
      try {
         /* Create a JSONObject from the string parameter */
         jsonNoteContent = (JSONObject) new JSONParser().parse(extraData);
      } catch (ParseException e) {
         e.printStackTrace();
      }

      /* If the JSONObject is correctly created, encode each attachment from the JSON */
      if (jsonNoteContent != null) {

         JSONArray jsonAttachments = (JSONArray) jsonNoteContent.get(KEY_ATTACH_ITEMS);

         /* For each attachment, translate set the current attachment properties with the translated JSON value */
         for (int i = 0; i < jsonAttachments.size(); i++) {
            JSONObject jsonAttach = (JSONObject) jsonAttachments.get(i);

            /* Set the standard properties */
            AttachmentItem attach = new AttachmentItem();
            attach.setName((String) jsonAttach.get(KEY_ATTACH_NAME));
            attach.setType((String) jsonAttach.get(KEY_ATTACH_TYPE));

            /* Decode and set the thumbnails of the attachment */
            byte[] decodedByte = Base64.decode((String) jsonAttach.get(KEY_ATTACH_THUMBNAILS), 0);
            attach.setThumbnails(BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length));

            /* Add the attachment to the result */
            attachments.add(attach);
         }
      }

      return attachments;
   }

   /**
    * Translates the text content and all the attachments of the note in a JSON string
    *
    * @param note The note to translate in JSON
    * @return The JSON string that encapsulates the text content and the attachment of the note
    */
   public static String toJSON(Note note) {
      /* This JSONObject will store the JSON encode of the note */
      JSONObject jsonNoteContent = new JSONObject();

      /* Add the note text content to the JSON */
      jsonNoteContent.put(KEY_TEXT_CONTENT, note.getContent());

      /* For each note attachment, add it to the JSON */
      JSONArray jsonAttachments = new JSONArray();
      for (AttachmentItem attach : note.getAttachments()) {
         JSONObject jsonAttach = new JSONObject();

         /* Decode the standard properties */
         jsonAttach.put(KEY_ATTACH_NAME, attach.getName());
         jsonAttach.put(KEY_ATTACH_TYPE, attach.getType());

         /* Encode the attachment thumbnails */
         Bitmap bm = attach.getThumbnails();
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         bm.compress(Bitmap.CompressFormat.PNG, 50, baos);
         byte[] byteArrayImage = baos.toByteArray();
         jsonAttach.put(KEY_ATTACH_THUMBNAILS, Base64.encodeToString(byteArrayImage, Base64.DEFAULT));

         /* Add the attachment to the list */
         jsonAttachments.add(jsonAttach);
      }

      /* Add all the JSON attachments to the result */
      jsonNoteContent.put(KEY_ATTACH_ITEMS, jsonAttachments);

      return jsonNoteContent.toJSONString();
   }
}